﻿using System;
using Game.Common;
using Game.ExtensibleObjects;
using Game.Objects;

namespace Game.Map.Extensions
{
    public class MovingExtension : IRuntimeExtension
    {
        public event EventHandler<MovingItemEventArgs> MovingItemChanged;

        readonly IGameMap _Map;
        readonly IMapField _MapField;

        Vehicle _MovingItem;

        public MovingExtension(
            IGameMap map,
            IMapField field)
        {
            _Map = map;
            _MapField = field;
        }

        public Vehicle MovingItem
        {
            get { return _MovingItem; }
            set
            {
                if (_MovingItem == value) return;

                var save = _MovingItem;
                _MovingItem = value;

                if (_MovingItem != null)
                {
                    UpdateVisible2(_Map, _MapField, _MovingItem);
                }
                else if (save != null && save.Owner == HumanPlayer.Player)
                {
                    _Map.SelectedX().Selected = _MapField;
                }

                FireChanged(save);
            }
        }

        void FireChanged(Vehicle oldItem)
        {
            if (MovingItemChanged != null)
            {
                MovingItemChanged(this, new MovingItemEventArgs(oldItem));
            }
        }

        static void UpdateVisible2(
            IGameMap map, 
            IMapField field,
            Vehicle item)
        {
            foreach (var view in map.Views)
            {
                if (item.Owner == view.Owner)
                {
                    UpdateVisible2(view, field);
                }
            }
        }

        static void UpdateVisible2(IGameMapView view, IMapField field)
        {
            if (field.MovingX().MovingItem == null)
            {
                return;
            }

            if (field.MovingX().MovingItem.Owner != view.Owner)
            {
                return;
            }

            var collection = MapUtil.GetArea(view, field.Point,
                field.MovingX().MovingItem.Movement.Max);
            foreach (var cursor in collection)
            {
                var f = view.Collection[cursor.Point];
                f.IsVisible = true;
            }

            {
                var f = view.Collection[field.Point];
                f.IsVisible = true;
            }
        }
    }

    public class MoveEventArgs : EventArgs
    {
        readonly IActionCallback _callback;
        readonly GamePath _path;
        readonly Vehicle _item;
        readonly GameTurn _gameTurn;

        public MoveEventArgs(
            IActionCallback callback,
            GamePath path,
            Vehicle item,
            GameTurn turn)
        {
            _callback = callback;
            _path = path;
            _item = item;
            _gameTurn = turn;
        }

        public GamePath Path
        {
            get { return _path; }
        }

        public Vehicle Item
        {
            get { return _item; }
        }

        public GameTurn GameTurn
        {
            get { return _gameTurn; }
        }

        public IActionCallback Callback
        {
            get { return _callback; }
        }

        public double Distance { get; set; }

        public bool IsHandled { get; set; }
    }

    public static class FieldMovingItemExtensionHelper
    {
        public static MovingExtension MovingX(this IMapField map)
        {
            return map.Extensions.Find<MovingExtension>();
        }
    }

    public class MovingItemEventArgs : EventArgs
    {
        readonly Vehicle _oldItem;

        public MovingItemEventArgs(Vehicle oldItem)
        {
            _oldItem = oldItem;
        }

        public Vehicle OldItem
        {
            get { return _oldItem; }
        }
    }

}
